//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//********************************************************* 

using System;
using Microsoft.TridentWordAddIn.Common;
using Microsoft.TridentWordAddIn.Server;
using System.Diagnostics;
using System.Collections;
using System.Windows.Forms;
using Microsoft.TridentWordAddIn.ResourceHelper;
using System.Collections.Generic;

namespace Microsoft.TridentWordAddIn.Presentation
{
    public partial class ServeSettingUserControl : BaseUserControl
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ServeSettingUserControl"/> class.
        /// </summary>
        public ServeSettingUserControl()
        {
            InitializeComponent();
        }

        #region Properties

        /// <summary>
        /// Gets the name of the job.
        /// </summary>
        /// <value>The name of the job.</value>
        public string JobName
        {
            get
            {
                return this.txtJobName.Text;
            }
        }

        /// <summary>
        /// Gets the name of the machine.
        /// </summary>
        /// <value>The name of the machine.</value>
        public string MachineName
        {
            get
            {
                if (this.cmbMachines.SelectedItem == null || this.cmbMachines.SelectedIndex == 0)
                {
                    return string.Empty;
                }

                return this.cmbMachines.SelectedItem.ToString();
            }
        }

        /// <summary>
        /// Gets the selected connection.
        /// </summary>
        /// <value>The selected connection.</value>
        public TridentConnection SelectedConnection
        {
            get
            {
                TridentConnection conn = null;
                IDictionaryEnumerator iterator = this.ControllerInstance.UserData.Connections.GetEnumerator();
                string cmbConnectionName =
                    this.cmbConnection.SelectedItem != null ?
                    this.cmbConnection.SelectedItem.ToString() :
                    string.Empty;
                if (!cmbConnectionName.IsNullOrEmpty())
                {
                    while (iterator.MoveNext())
                    {
                        if (cmbConnectionName.Compare(iterator.Key.ToString()))
                        {
                            conn = iterator.Value as TridentConnection;
                            break;
                        }
                    }
                }

                return conn;
            }
        }

        /// <summary>
        /// Removes the event handlers.
        /// </summary>
        public void UnregisterEventHandlers()
        {
            this.ControllerInstance.OnConnectionChanged -= new EventHandler<ConnectionChangedEventArgs>(Controller_OnConnectionChanged);
            base.Disposing();
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Initializes the specified connection auto update.
        /// </summary>
        /// <param name="connectionAutoUpdate">if set to <c>true</c> [connection auto update].</param>
        public override void Initialize(bool connectionAutoUpdate)
        {
            try
            {
                base.Initialize(connectionAutoUpdate);
                this.ControllerInstance.OnConnectionChanged += new EventHandler<ConnectionChangedEventArgs>(Controller_OnConnectionChanged);

                this.UpdateMachines();
                this.UpdateConnections();
            }
            catch (ConnectionFailedException ex)
            {
                Trace.WriteLine("Exception" + ex, TraceLevel.Error.ToString());
            }
        }

        /// <summary>
        /// Resets this instance.
        /// </summary>
        public void Reset()
        {
            this.txtJobName.Text = string.Empty;
            if (this.IsConnectionAutoUpdate)
            {                
                this.UpdateConnections();
                this.UpdateMachines();
            }
        }

        /// <summary>
        /// Validates the selection.
        /// </summary>
        /// <returns></returns>
        public bool ValidateSelection()
        {
            bool failed = false;
            string message = string.Empty;

            if (this.txtJobName.Text.Trim().IsNullOrEmpty())
            {
                failed = true;
                message = ResourceFetcher.GetString("InvalidJobName");
            }

            if (this.MachineName.IsNullOrEmpty())
            {
                failed = true;
                message += "\n";
                message += ResourceFetcher.GetString("NoMachineSelected");
            }
            else if (!this.Server.IsMachineOnline(this.MachineName))
            {
                failed = true;
                message += "\n";
                message += ResourceFetcher.GetString("MachineNotAvailable");
            }

            if (cmbConnection.Items.Count == 0)
            {
                failed = true;
                message += "\n";
                message += ResourceFetcher.GetString("NoConnection");
            }

            if (this.SelectedConnection == null)
            {
                failed = true;
                message += "\n";
                message += ResourceFetcher.GetString("NoConnectionSelected");
            }

            if (failed)
            {                
                MessageBoxHelper.ShowDefault(message);
            }

            return !failed;
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Updates the machines.
        /// </summary>
        private void UpdateMachines()
        {
            this.cmbMachines.Items.Clear();
            List<string> machines = new List<string>();
            machines.Add(ResourceFetcher.GetString("SelectMachine"));
            machines.AddRange(ControllerInstance.Server.Machines);            
            this.cmbMachines.Items.AddRange(machines.ToArray());
            this.cmbMachines.SetDefaultSelection();
        }

        /// <summary>
        /// Updates the connections.
        /// </summary>
        private void UpdateConnections()
        {
            int loopCount = 0;
            int selectedIndex = 0;
            string currentConnection = this.ControllerInstance.CurrentConnectionName;                          
            this.cmbConnection.Items.Clear();
            IDictionaryEnumerator iterator = this.ControllerInstance.UserData.Connections.GetEnumerator();
            this.cmbConnection.Items.Add("- Select Connection -");
            while (iterator.MoveNext())
            {
                loopCount++;
                string connName = iterator.Key.ToString();
                this.cmbConnection.Items.Add(connName);
                if (selectedIndex == 0)
                {
                    if (connName.Compare(currentConnection))
                    {
                        selectedIndex = loopCount;
                    }
                }
            }

            this.cmbConnection.SelectedIndex = selectedIndex;
        }

        /// <summary>
        /// Handles the OnConnectionChanged event of the Controller control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Microsoft.TridentWordAddIn.Common.ConnectionChangedEventArgs"/> instance containing the event data.</param>
        private void Controller_OnConnectionChanged(object sender, ConnectionChangedEventArgs e)
        {
            if (e.DocumentKey == DocumentKey)
            {
                this.UpdateConnections();
                this.UpdateMachines();
            }
        }

        #endregion
    }
}
